/**
 * congressNewExt
 *
 * @author h.hess@clienthouse.com
 * 
 * Controller extension for BXDE_Congress__c standard controller, provides
 * additional functionality for entering new congresses via congressNew
 * Visualforce page.
 *
 * v1: initial version
 * v2: added functionality for multiple record types
 * 
 */
public class congressNewExt {
	
	// stores the congress to be created    
    public BXDE_Congress__c congress { get; set; }
    
    // stores a dynamic list of opening hours
    public OpeningHour[] openingHours { get; set; }
    
    // indicats if opening hours make sense
    public Boolean validRange { get; set; }
    
    // provides picklist entries for record type selection
    public SelectOption[] availRecordTypes { get; set; }
    
    // indicates if record type selection must be rendered
    public Boolean displayRecordTypeSelect { get; set; }
    
    private ApexPages.StandardController ctrl;
	
	// default extension constructor
	public congressNewExt(ApexPages.StandardController ctrl){
		this.ctrl = ctrl;
		
		// get the new congress record
		this.congress = (BXDE_Congress__c)ctrl.getRecord();
		
		// set some custom user information
		User currentUser = [select BXDE_Marketing_Sales_Leitung__c, Department from User where Id = :UserInfo.getUserId()];
		this.congress.BXDE_Manager__c = currentUser.BXDE_Marketing_Sales_Leitung__c;
		this.congress.BXDE_Business_Unit__c = currentUser.Department;
		
		this.congress.BXDE_Grant_Number__c = 'GGER';
		this.openingHours = buildOpeningHours(Date.today(), Date.today());
		
		// if user got her via standard record type selection
		ApexPages.PageReference page = ApexPages.currentPage();
		if(page.getParameters().containsKey('RecordType')){
			this.congress.RecordTypeId = page.getParameters().get('RecordType');
		}
		
		// handle available record types
		availRecordTypes = getRecordTypesByUser();
		if(availRecordTypes.size() == 1){
			displayRecordTypeSelect = false;
			this.congress.RecordTypeId = availRecordTypes[0].getValue();
		} else {
			displayRecordTypeSelect = true;
		}
						
		// new congress so range can't be valid initially
		this.validRange = false;
	}
    
    /**
     * Builds the list of opening hours based upon the passed start and end dates.
     * @param Date startDate
     * @param Date endDate
     * @return openingHours
     */
    public OpeningHour[] buildOpeningHours(Date startDate, Date endDate){
        Integer numDays = startDate.daysBetween(endDate) + 1;
        System.debug(numDays);
        
        // build list of opening hours
        OpeningHour[] openingHrs = new List<OpeningHour>();
        for(Integer i = 0; i < numDays; i++){
            OpeningHour oh = new OpeningHour(startDate + i, 
            Time.newInstance(9, 0, 0, 0), Time.newInstance(18, 0, 0, 0));
            openingHrs.add(oh);
        }
        return openingHrs;
    }
    
    /**
     * Returns the list of opening hours as a formatted string.
     */
    private String openingHoursToStr(){
    	String ohStr = '';
    	for(OpeningHour oh: openingHours){
    		if(oh.toStr() != null) ohStr += oh.toStr() + '\n';
    	}
    	return ohStr;
    }
    
    /**
     * Return the available record types as picklist values.
     */
    private SelectOption[] getRecordTypesByUser(){
    	// dynamic apex is cool
    	Schema.DescribeSObjectResult result = Schema.SObjectType.BXDE_Congress__c;
    	Schema.RecordTypeInfo[] recordTypes = result.getRecordTypeInfos();
    	SelectOption[] recordTypeOptions = new List<SelectOption>();
    	for(Schema.RecordTypeInfo rti : recordTypes){
    		if(rti.isAvailable() && rti.getName() != 'Master'){
    			recordTypeOptions.add(new SelectOption(rti.getRecordTypeId(), rti.getName()));
    		}
    	}
    	return recordTypeOptions;
    }
    
    /**
     * Action method, rebuilds the opening hours from the updated congress data.
     * @return PageReference null
     */
    public PageReference refreshOpeningHours(){
        System.debug(congress); 
        if(congress.BXDE_Start_Date__c != null && congress.BXDE_End_Date__c != null){ 
        	// check precedence seperately to throw meaningful exceptions
        	if(congress.BXDE_End_Date__c < congress.BXDE_Start_Date__c){
        		congress.BXDE_End_Date__c.addError('Das Enddatum des Kongresses darf nicht vor dem Startdatum liegen.');
        		this.validRange = false;
        		return null;
        	}
        	// range is valid, build opening hours and do not redirect
        	this.validRange = true;
            this.openingHours = buildOpeningHours(congress.BXDE_Start_Date__c, congress.BXDE_End_Date__c);
            return null;
        }
        this.validRange = false;
        return null;
    }
    
    /**
     * Switches between record type selection, page and redirect
     */
    public PageReference setCongressRecordType(){
    	if(congress.RecordTypeId == '012200000000sII'){
    		displayRecordTypeSelect = false;
    		return null;
    	} else if(congress.RecordTypeId != null) {
    		ApexPages.PageReference pageRef = new ApexPages.PageReference('/a0c/e?RecordType=' + congress.RecordTypeId + '&nooverride=1&ent=01I200000001HVL');
    		return pageRef;
    	} else {
    		displayRecordTypeSelect = true;
    		return null;
    	}
    }
    
    /**
     * Overrides the standard save functionality.
     */
    public PageReference save(){
    	
    	// make sure required start and end date are filled out
    	if(congress.BXDE_Start_Date__c == null || congress.BXDE_End_Date__c == null){
    		congress.addError('Bitte geben Sie ein Start- und Enddatum für den Kongress an.');
    		return null;
    	}
    	
    	// convert opening hours to string
    	congress.BXDE_Opening_Hours_Industrial_Exhibition__c = this.openingHoursToStr();
    	
    	// save!
    	try {
    		insert congress;
    	} catch(System.DmlException dex){
    		System.debug(dex);
    		String msg = 'Der Datensatz konnte nicht gespeichert werden. ';
    		msg += dex.getDmlMessage(0);
   	    	ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, msg));
   	    	return null;
    	}
    	return new PageReference('/apex/manageRollUps?id=' + congress.Id + '&isNew=1&displayType=RollUp');
    }
        
    /**
     * Model for the opening hour object
     */
    public class OpeningHour {
        public String dayStr { get; set; }
        public Date dDate { get; set; }
        public String startTimeStr { get; set; }
        public String endTimeStr { get; set; }
        public List<SelectOption> options { get; set; }
        
        public OpeningHour(Date dDate, Time startTime, Time endTime){
            this.dDate = dDate;
            this.startTimeStr = startTime.hour() + ':00';
            this.endTimeStr = endTime.hour() + ':00';
            this.dayStr = DateUtil.getLocalDayString(dDate);
            
            options = new List<SelectOption>();
            // add the null option
            options.add(new SelectOption('none', '-None-'));
            for(Integer i = 6; i < 23; i++){
                options.add(new SelectOption(i + ':00', i + ':00'));
                options.add(new SelectOption(i + ':30', i + ':30'));
            }
        }
        
        public String toStr(){
        	if(startTimeStr != 'none' && endTimeStr != 'none'){
        		System.debug('dayStr: ' + dayStr + ' date ' + dDate);
        		return dayStr.substring(0, 2) + ' ' + dDate.format() + ' ' + startTimeStr + ' - ' + endTimeStr;
        	}
        	return null;
        }
    }
}